/**
 * This class creates the Organizational and sub process-->AppService graphs
 */
class ServicesGraphCreator
{
    Organization org
    Logger logger = new Logger()


    ServicesGraphCreator(Organization org)
    {
        this.org = org
    }

    /**
     * produces the org svc->BF->BP->SP graph - its really big
     */
    def createWholeOrgGraph()
    {
        Graphviz ggen = new Graphviz()

        //println "Operating Date:"+ opDate
        logger.info("Generating the graphics for the Organization:"+org.name)

        // starts a new graph object - false = horizontal, true = vertical
        ggen.newGraph(org.name, true)
        def orgSvcGroup = ggen.newGraphGroup("Org Services")

        // box for BFs
        def bfGroup = ggen.newGraphGroup("Business Functions")

        // box for BPs
        def bpGroup = ggen.newGraphGroup("Business Processes")
        //def spGroup = ggen.newGraphGroup("Sub Processes")

        def rootNode = ggen.newGraphNode(org.name, org.name)

        def ctr = 2;
        org.orgServices.each { key, myOrgService -> 
            println  "\t|----OS:" + myOrgService.name
            def orgSvcNode = ggen.newGraphNode(myOrgService.name, myOrgService.name)
            orgSvcNode.setMemberOf(orgSvcGroup)
            ggen.newGraphEdge("", rootNode, orgSvcNode)

            myOrgService.businessFunctions.each { bfkey, myBusinessFunction ->
                println "\t\t|----BF:" + myBusinessFunction.name
                def bfNode = ggen.newGraphNode(myBusinessFunction.name, myBusinessFunction.name)
                bfNode.setMemberOf(bfGroup)
                ggen.newGraphEdge("", orgSvcNode, bfNode)

                myBusinessFunction.businessProcesses.each { bpkey, myBusinessProcess ->
                    println "\t\t\t|----BP:" + myBusinessProcess.name
                    println "\t\t\t\t\t|-----timeline:" + myBusinessProcess.timelineItem
                    def bpNode = ggen.newGraphNode(myBusinessProcess.name, myBusinessProcess.name)
                    bpNode.setMemberOf(bpGroup)
                    ggen.newGraphEdge("", bfNode, bpNode)

                    // Box for SPs
                    def bpForSpGroup = ggen.newGraphGroup("BP:"+myBusinessProcess.name)

                    myBusinessProcess.subProcesses.each { spKey, mySubProcess ->
                        println "\t\t\t\t|----SP:" + mySubProcess.name
                        def spNode = ggen.newGraphNode(mySubProcess.name, mySubProcess.name)
                        spNode.setMemberOf(bpForSpGroup)
                        ggen.newGraphEdge("", bpNode, spNode)

                        /*
                        mySubProcess.appServices.each { appSvcKey, myAppService ->
                            println "\t\t\t\t\t|----AppSvc:" + myAppService.name
                            def appSvcNode = ggen.newGraphNode(myAppService.name, myAppService.name)
                            ggen.newGraphEdge("", spNode, appSvcNode)
                        }
                        */
                    }
                }
            }
        }

        def dotFilePath = ggen.genDotFile(org.name.replace(" ", "_")+"_whole")
        ggen.genDotImage(".", dotFilePath)        
    }


    /**
     * produces the org svc->BF->BP graph
     */
    def createO2BF2BPGraph()
    {
        Graphviz ggen = new Graphviz()

        //println "Operating Date:"+ opDate
        logger.info("Generating the graphics for the Organization:"+org.name)
        
        // starts a new graph object - false = horizontal, true = vertical
        ggen.newGraph(org.name, true)
        
        def orgSvcGroup = ggen.newGraphGroup("Org Services")
        def bfGroup = ggen.newGraphGroup("Business Functions")
        def bpGroup = ggen.newGraphGroup("Business Processes")

        def rootNode = ggen.newGraphNode(org.name, org.name)

        def ctr = 2;
        org.orgServices.each { key, myOrgService -> 
            println  "\t|----OS:" + myOrgService.name
            def orgSvcNode = ggen.newGraphNode(myOrgService.name, myOrgService.name)
            orgSvcNode.setMemberOf(orgSvcGroup)
            ggen.newGraphEdge("", rootNode, orgSvcNode)

            myOrgService.businessFunctions.each { bfkey, myBusinessFunction ->
                println "\t\t|----BF:" + myBusinessFunction.name
                def bfNode = ggen.newGraphNode(myBusinessFunction.name, myBusinessFunction.name)
                bfNode.setMemberOf(bfGroup)
                ggen.newGraphEdge("", orgSvcNode, bfNode)

                myBusinessFunction.businessProcesses.each { bpkey, myBusinessProcess ->
                    println "\t\t\t|----BP:" + myBusinessProcess.name
                    //println "\t\t\t\t\t|-----timeline:" + myBusinessProcess.timelineItem
                    def bpNode = ggen.newGraphNode(myBusinessProcess.name, myBusinessProcess.name)
                    bpNode.setMemberOf(bpGroup)
                    ggen.newGraphEdge("", bfNode, bpNode)

                    /*
                    myBusinessProcess.subProcesses.each { spKey, mySubProcess ->
                        println "\t\t\t\t|----SP:" + mySubProcess.name
                        def spNode = ggen.newGraphNode(mySubProcess.name, mySubProcess.name)
                        ggen.newGraphEdge("", bpNode, spNode)

                        mySubProcess.appServices.each { appSvcKey, myAppService ->
                            println "\t\t\t\t\t|----AppSvc:" + myAppService.name
                            def appSvcNode = ggen.newGraphNode(myAppService.name, myAppService.name)
                            ggen.newGraphEdge("", spNode, appSvcNode)
                        }
                    }
                    */
                }
            }
        }

        def dotFilePath = ggen.genDotFile(org.name.replace(" ", "_")+"_o2bf2bp")
        ggen.genDotImage("", dotFilePath)        
    }
    

    /**
     * produces the BP --> SP --> AppSvc graphs
     */
    def createBP2SP2ASGraphs()
    {
        Graphviz ggen = new Graphviz()

        //println "Operating Date:"+ opDate
        logger.info("Generating the graphics for the Organization:"+org.name)
        
        // starts a new graph object - false = horizontal, true = vertical

        def ctr = 2;
        org.orgServices.each { key, myOrgService -> 
            //println  "\t|----OS:" + myOrgService.name
            //def orgSvcNode = ggen.newGraphNode(myOrgService.name, myOrgService.name)
            //orgSvcNode.setMemberOf(orgSvcGroup)
            //ggen.newGraphEdge("", rootNode, orgSvcNode)

            myOrgService.businessFunctions.each { bfkey, myBusinessFunction ->
                //println "\t\t|----BF:" + myBusinessFunction.name
                //def bfNode = ggen.newGraphNode(myBusinessFunction.name, myBusinessFunction.name)
                //bfNode.setMemberOf(bfGroup)
                //ggen.newGraphEdge("", orgSvcNode, bfNode)

                myBusinessFunction.businessProcesses.each { bpkey, myBusinessProcess ->
                    println "\t\t\t|----BP:" + myBusinessProcess.name
                    println "\t\t\t\t\t|-----timeline:" + myBusinessProcess.timelineItem

                    ggen.newGraph("BP:" + myBusinessProcess.name, false)

                    def bpNode = ggen.newGraphNode(myBusinessProcess.name, myBusinessProcess.name)
                    def bpGroup = ggen.newGraphGroup("Business Process")
                    bpNode.setMemberOf(bpGroup)

                    def spGroup = ggen.newGraphGroup("Sub Processes")

                    def prevspNode

                    myBusinessProcess.subProcesses.each { spKey, mySubProcess ->
                        println "\t\t\t\t|----SP:" + mySubProcess.name
                        def spNode = ggen.newGraphNode(mySubProcess.name, mySubProcess.name)
                        //ggen.newGraphEdge("", bpNode, spNode)

                        spNode.setMemberOf(spGroup)

                        if(prevspNode!=null)
                            ggen.newGraphEdge("", prevspNode, spNode)
                        prevspNode = spNode

                        def appSvcsGroup = ggen.newGraphGroup("App Services")
                        mySubProcess.appServices.each { appSvcKey, myAppService ->
                            println "\t\t\t\t\t|----AppSvc:" + myAppService.name
                            def appSvcNode = ggen.newGraphNode(myAppService.name, myAppService.name)
                            ggen.newGraphEdge("", spNode, appSvcNode)
                            
                            appSvcNode.setMemberOf(appSvcsGroup)
                        } // appServices
                    }//subProcesses

                    def dotFilePath = ggen.genDotFile(myBusinessProcess.name.replace(" ", "_"))
                    ggen.genDotImage(ctr+".", dotFilePath)
                    ctr++
                }//businessProcesses
            }//businessFunctions
        }//orgServices
    }    

    
    /**
     * create the full list of Sub process-->App Svc graphs
     */
    def createSubProcessGraphs()
    {
        Graphviz ggen = new Graphviz()

        //println "Operating Date:"+ opDate
        logger.info("Generating the graphics for Subprocesses:")
        
        def ctr = 2;
        org.orgServices.each { key, myOrgService -> 
            //println  "\t|----OS:" + myOrgService.name

            myOrgService.businessFunctions.each { bfkey, myBusinessFunction ->
                //println "\t\t|----BF:" + myBusinessFunction.name

                myBusinessFunction.businessProcesses.each { bpkey, myBusinessProcess ->
                    //println "\t\t\t|----BP:" + myBusinessProcess.name
                    //println "\t\t\t\t|-----timeline:" + myBusinessProcess.timelineItem

                    myBusinessProcess.subProcesses.each { spKey, mySubProcess ->

                        ggen.newGraph("SP:" + mySubProcess.name, true)

                        mySubProcess.appServices.each { appSvcKey, myAppService ->

                            def a = ggen.newGraphNode(myAppService.sourceAppComponentName, myAppService.sourceAppComponentName)
                            a.getInfo().setShapeComponent()
                            def b = ggen.newGraphNode(myAppService.sinkAppComponentName, myAppService.sinkAppComponentName)
                            b.getInfo().setShapeComponent()

                            def ggroup = ggen.newGraphGroup(myAppService.sourceSystemName)
                            a.setMemberOf(ggroup)

                            ggroup = ggen.newGraphGroup(myAppService.sinkSystemName)
                            b.setMemberOf(ggroup)

                            def str1 = myAppService.isExternal?"E":"I"
                            def str = "("+str1+") " + "" + myAppService.name+ " (" + myAppService.dataObjectType+":"+myAppService.dataObjectName + ")"

                            def abedge = ggen.newGraphEdge(str, a, b)                            

                            // ctr++
                            // println ctr+ ". " + mySubProcess.name + ": " + mySubProcess.timelineItem
                            // def timelineItem = mySubProcess.timelineItem
                            // eventPts.add(getEventPt(mySubProcess.name, timelineItem, opDate))
                        }

                        //ggen.genDotFile("test")
                        def dotFilePath = ggen.genDotFile(mySubProcess.name.replace(" ", "_"))
                        ggen.genDotImage(ctr+".", dotFilePath)

                        ctr++
                    }
                }
            }
        }
    }
}
